package org.rency.ues.engine.repository.impl;

import org.rency.ues.dal.dao.EnDataDao;
import org.rency.ues.dal.entity.EnDataDO;
import org.rency.ues.domain.model.DataHashDomain;
import org.rency.ues.domain.model.EnDataDomain;
import org.rency.ues.engine.converter.DataHashConverter;
import org.rency.ues.engine.converter.EncryptConverter;
import org.rency.ues.engine.repository.DataHashRepository;
import org.rency.ues.engine.repository.EnDataRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

public class EnDataRepositoryImpl implements EnDataRepository {
	
	private static final Logger logger = LoggerFactory.getLogger(EnDataRepositoryImpl.class);

	private EnDataDao                   enDataDao;
	
	private DataHashRepository          dataHashRepository;
	
	private TransactionTemplate         transactionTemplate;
	
	@Override
	public EnDataDomain get(int id) {
		return EncryptConverter.convert(enDataDao.get(id));
	}

	@Override
	public EnDataDomain getByTicket(String ticket) {
		return EncryptConverter.convert(enDataDao.getByTicket(ticket));
	}

	@Override
	public boolean delete(int id) {
		return enDataDao.delete(id) == 1;
	}

	@Override
	public boolean deleteByTicket(String ticket) {
		return enDataDao.deleteByTicket(ticket) == 1;
	}

    @Override
    public boolean deleteWithRela(final String ticket) {
        return transactionTemplate.execute(new TransactionCallback<Boolean>() {
            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                Object savePoint = status.createSavepoint();
                try{
                    if(!deleteByTicket(ticket)) {
                        throw new IllegalArgumentException("删除加密数据失败");
                    }
                    if(!dataHashRepository.deleteByTicket(ticket)){
                        throw new IllegalArgumentException("删除加密数据Hash失败");
                    }
                    return true;
                }catch(Exception e){
                    logger.error("删除数据失败.Ticket={}.",ticket,e);
                    status.rollbackToSavepoint(savePoint);
                    return false;
                }finally {
                    status.releaseSavepoint(savePoint);
                    status.flush();
                }
            }
        });
    }

	@Override
	public boolean saveEnDataWithHash(String hash, final EnDataDomain domain) {
		DataHashDomain orgiHashDomain = dataHashRepository.getByHash(hash);
		if(orgiHashDomain != null){
			domain.setTicket(orgiHashDomain.getTicket());
			return true;
		}
		final DataHashDomain hashDomain = DataHashConverter.build(domain.getTicket(),hash);
		final EnDataDO entity = EncryptConverter.convert(domain);
		return transactionTemplate.execute(new TransactionCallback<Boolean>() {
			@Override
			public Boolean doInTransaction(TransactionStatus status) {
				Object savepoint = status.createSavepoint();
				try {
					boolean ret = dataHashRepository.save(hashDomain);
					if (!ret) {
						throw new IllegalArgumentException("Hash信息存储失败");
					}
					if (enDataDao.insert(entity) != 1) {
						throw new IllegalArgumentException("加密信息存储失败");
					}
					domain.setId(entity.getId());
					return true;
				}catch (Exception e){
					logger.error("数据存储异常.",e);
					status.rollbackToSavepoint(savepoint);
					return false;
				}finally {
					status.releaseSavepoint(savepoint);
				}

			}
		});
	}

	public void setEnDataDao(EnDataDao enDataDao) {
		this.enDataDao = enDataDao;
	}

	public void setDataHashRepository(DataHashRepository dataHashRepository) {
		this.dataHashRepository = dataHashRepository;
	}

	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}

}
